const h = window.React.createElement

export function renderChannels(channels) {
  return h("nav", { className: "c-feeds-menu" },
    groupByDate(channels).map((feedByDate) =>
      h("fieldset", { className: "c-date-view" },
        h("legend", { className: "c-date-title" },
          h("span", null, renderLocalDate(feedByDate.startDate))
        ),
        h("div", { className: "c-date-content" },
          feedByDate.channels.map((channel) => {
            const url = new URL(location.href);
            url.searchParams.set("feedUrl", channel.url);
            return channel.items.map((item) =>
              h("article", { className: "c-item" },
                h("a", { href: channel.homeUrl, title: channel.title },
                  h("img", { className: "c-item-icon", alt: "", loading: "lazy", src: getGoogleFaviconUrl(item.url) })
                ),
                h("a", { href: item.url, className: "c-item-title js-visit-target", target: "_blank" }, item.title)
              )
            );
          })
        )
      )
    )
  )
}

function renderLocalDate(rawDate) {
  return new Date(rawDate).toLocaleString("zh-CN", {
    year: "numeric",
    month: "numeric",
    day: "numeric",
  });
}

function groupByDate(channels) {
  const flatItems = channels
    .flatMap((channel) =>
      channel.items
        .map((item) => ({
          datePublished: getStartOfDayDate(item.timePublished),
          timePublished: item.timePublished,
          channel: {
            url: channel.url,
            title: channel.title,
            homeUrl: channel.homeUrl ?? item.url,
          },
          icon: getGoogleFaviconUrl(item.url),
          title: item.title,
          url: item.url,
        }))
    )
    .sort((a, b) => b.timePublished - a.timePublished);

  // The sorting of items guarantee that the channels and their items are sorted from new to old
  const feedsByDate = flatItems.reduce((acc, item) => {
    const existingDate = acc.find((group) => group.startDate === item.datePublished);
    if (existingDate) {
      const existingFeed = existingDate.channels.find((channel) => channel.url === item.channel.url);

      if (existingFeed) {
        existingFeed.items.push(item);
      } else {
        existingDate.channels.push({
          title: item.channel.title,
          url: item.channel.url,
          homeUrl: item.channel.homeUrl,
          items: [item],
        });
      }
    } else {
      acc.push({
        startDate: item.datePublished,
        channels: [{ title: item.channel.title, url: item.channel.url, homeUrl: item.channel.homeUrl, items: [item] }],
      });
    }
    return acc;
  }, []);

  return feedsByDate;
}

function getStartOfDayDate(date) {
  const d = new Date(date);
  d.setHours(0, 0, 0, 0);
  return d.getTime();
}

function getGoogleFaviconUrl(pageUrl) {
  return `https://www.google.com/s2/favicons?domain=${new URL(pageUrl).host}&sz=32`;
}
